/*
 * Copyright 2008 - 2009 Lars Heuer (heuer[at]semagia.com). All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.semagia.atomico.server.storage;

import com.semagia.atomico.server.UnsupportedMediaTypeException;
import com.semagia.atomico.server.dm.ICollectionInfo;
import com.semagia.atomico.server.dm.IFragment;
import com.semagia.atomico.server.dm.IFragmentInfo;
import com.semagia.atomico.server.dm.ISnapshot;
import com.semagia.atomico.server.dm.ISnapshotInfo;

/**
 * EXPERIMENTAL Storage that supports modifications (i.e. adding collections, snapshots, 
 * fragments).
 * 
 * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
 */
public interface IModifiableStorage extends IStorage {

    /**
     * Adds a collection.
     *
     * @param collectionInfo The collection which should be added to the storage.
     *                       If {@link ICollectionInfo#getCollectionId()} returns null,
     *                       The storage must generate an identifier.
     * @return A collection which contains all information about the added collection
     *         (@link ICollectionInfo#getCollectionId()} must not be null.
     */
    ICollectionInfo addCollection(ICollectionInfo collectionInfo) throws StorageException;

    /**
     * Updates a collection.
     *
     * @param collectionInfo The collection which should be updated.
     * @return A collection which contains all information about the updated collection.
     */
    ICollectionInfo updateCollection(ICollectionInfo collectionInfo) throws StorageException;

    /**
     * Deletes a collection.
     * 
     * The storage is responsible to delete all snapshots and fragments of the collection.
     *
     * @param collectionId The collection identifier {@link ICollectionInfo#getCollectionId()}
     *                     of the collection which should be deleted.
     * @return {@code true} if the collection was deleted, otherwise {@code false}.
     * @throws StorageException In case of an unexpected error.
     */
    boolean deleteCollection(String collectionId) throws StorageException;

    /**
     * Adds a snapshot to an existing collection.
     *
     * @param collectionId The collection identifier ({@link ICollectionInfo#getCollectionId()}).
     * @param snapshot The snapshot to add.
     * @return A SnapshotInfo instance.
     * @throws StorageException In case of an unexpected error.
     * @throws IllegalSnapshotException If the snapshot is not valid (i.e. a syntax error).
     * @throws UnsupportedMediaTypeException If the media type is not supported by the store.
     */
    ISnapshotInfo addSnapshot(String collectionId, ISnapshot snapshot) throws StorageException, IllegalSnapshotException, UnsupportedMediaTypeException;

    /**
     * Deletes a snapshot.
     *
     * @param collectionId The collection identifier ({@link ICollectionInfo#getId()}).
     * @param snapshotId The identifier of the snapshot which should be deleted ({@link ISnapshotInfo#getSnapshotId()}).
     * @return {@code true} if the snapshot was deleted, otherwise {@code false}.
     * @throws StorageException In case of an unexpected error.
     */
    boolean deleteSnapshot(String collectionId, String snapshotId) throws StorageException;

    /**
     * Adds a fragment to an existing collection.
     *
     * @param collectionId The collection identifier ({@link ICollectionInfo#getCollectionId()}).
     * @param fragment The fragment to add.
     * @return A FragmentInfo instance.
     * @throws StorageException In case of an unexpected error.
     * @throws IllegalFragmentException If the fragment is not valid (i.e. missing identity of particular subjects or a syntax error).
     * @throws UnsupportedMediaTypeException If the media type is not supported by the store.
     */
    IFragmentInfo addFragment(String collectionId, IFragment fragment) throws StorageException, IllegalFragmentException, UnsupportedMediaTypeException;

}
